/**
  ******************************************************************************
  * @file           : Base64.h
  * @author         : livio[yuanfeng1897@outlook.com]
  * @brief          : None
  * @attention      : None
  * @date           : 2023/3/2
  ******************************************************************************
  */



#ifndef CPPDEMO_BASE64_H
#define CPPDEMO_BASE64_H

#define BASE64_ENCODE_OUT_SIZE(s)   (((s) + 2) / 3 * 4)
#define BASE64_DECODE_OUT_SIZE(s)   (((s)) / 4 * 3)

#ifdef __cplusplus
extern "C"
{
#endif // !__cplusplus

// @return encoded size
int base64_encode(const unsigned char *in, unsigned int inlen, char *out);

// @return decoded size
int base64_decode(const char *in, unsigned int inlen, unsigned char *out);
#ifdef __cplusplus
};
#endif // !__cplusplus

#ifdef __cplusplus

#include <cstring>
#include <string>

static inline std::string Base64Encode(const unsigned char *data, unsigned int len) {
    int encoded_size = BASE64_ENCODE_OUT_SIZE(len);
    std::string encoded_str(encoded_size + 1, 0);
    encoded_size = base64_encode(data, len, (char *) encoded_str.data());
    encoded_str.resize(encoded_size);
    return encoded_str;
}

static inline std::string Base64Decode(const char *str, unsigned int len = 0) {
    if (len == 0) len = strlen(str);
    int decoded_size = BASE64_DECODE_OUT_SIZE(len);
    std::string decoded_buf(decoded_size + 1, 0);
    decoded_size = base64_decode(str, len, (unsigned char *) decoded_buf.data());
    decoded_buf.resize(decoded_size);
    return decoded_buf;
}

#endif // !__cplusplus

#endif //CPPDEMO_BASE64_H
